import { useMemo } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';
import type { TrainResult } from '@/types/job';

interface TrainResultProps {
  result?: TrainResult;
}

const palette = ['#2563eb', '#16a34a', '#f59e0b', '#ec4899', '#6366f1'];

const toNumber = (value: unknown): number | null => {
  if (value == null) return null;
  const numeric = Number(value);
  return Number.isFinite(numeric) ? numeric : null;
};

const formatFraction = (value: number | string | Array<number | string>): string => {
  const numeric = Array.isArray(value) ? Number(value[0]) : Number(value);
  return Number.isFinite(numeric) ? numeric.toFixed(4) : '—';
};

const formatPercent = (value: number | string | Array<number | string>): string => {
  const numeric = Array.isArray(value) ? Number(value[0]) : Number(value);
  return Number.isFinite(numeric) ? `${numeric.toFixed(2)}%` : '—';
};

const sortKey = (label: string): number => Number(label.split(' ')[1] ?? 0);

export default function TrainResultView({ result }: TrainResultProps) {
  const metrics = Array.isArray(result?.Metrics) ? result.Metrics : [];

  const {
    chartSeries,
    classAccuracySeries,
    classAccuracyKeys,
    availability,
  } = useMemo(() => {
    const loss = metrics.map((item, index) => ({
      epoch: toNumber(item.epoch) ?? index,
      train: toNumber(item.Train_Loss),
      test: toNumber(item.Test_Loss),
    }));

    const chartSeries = metrics.map((item, index) => ({
      epoch: toNumber(item.epoch) ?? index,
      train: toNumber(item.Train_Loss),
      test: toNumber(item.Test_Loss),
      oa: toNumber(item.OA),
      kappa: toNumber(item.Kappa),
      precision: toNumber(item.Precision),
      recall: toNumber(item.Recall),
    }));

    const keys = new Set<string>();
    const classSeries = metrics.map((item, index) => {
      const epoch = toNumber(item.epoch) ?? index;
      const record: Record<string, number | null> = { epoch };

      if (Array.isArray(item.Class_Accuracy)) {
        item.Class_Accuracy.forEach((value, idx) => {
          const label = `类别 ${idx + 1}`;
          keys.add(label);
          record[label] = toNumber(value);
        });
      }

      return record;
    });

    const sortedKeys = Array.from(keys).sort((a, b) => sortKey(a) - sortKey(b));

    const availability = {
      loss: loss.some((entry) => entry.train != null || entry.test != null),
      oa: chartSeries.some((entry) => entry.oa != null),
      kappa: chartSeries.some((entry) => entry.kappa != null),
      precision: chartSeries.some((entry) => entry.precision != null),
      recall: chartSeries.some((entry) => entry.recall != null),
      classAccuracy:
        sortedKeys.length > 0 &&
        classSeries.some((entry) => sortedKeys.some((key) => entry[key] != null)),
    };

    return {
      chartSeries,
      classAccuracySeries: classSeries,
      classAccuracyKeys: sortedKeys,
      availability,
    };
  }, [metrics]);

  if (metrics.length === 0) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>训练指标</CardTitle>
        </CardHeader>
        <CardContent>
          <p className="text-sm text-muted-foreground">暂无训练指标数据。</p>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>训练指标</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <Tabs defaultValue="loss" className="space-y-4">
          <TabsList className="flex-wrap justify-start gap-2 bg-muted/30 p-1">
            <TabsTrigger value="loss">Loss 曲线</TabsTrigger>
            {availability.oa && <TabsTrigger value="oa">OA</TabsTrigger>}
            {availability.kappa && <TabsTrigger value="kappa">Kappa</TabsTrigger>}
            {availability.precision && <TabsTrigger value="precision">Precision</TabsTrigger>}
            {availability.recall && <TabsTrigger value="recall">Recall</TabsTrigger>}
            {availability.classAccuracy && (
              <TabsTrigger value="class-accuracy">类别准确率</TabsTrigger>
            )}
          </TabsList>

          <TabsContent value="loss" className="mt-0 mb-0">
            {availability.loss ? (
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={chartSeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatFraction} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  <Line
                    type="monotone"
                    dataKey="train"
                    name="Train Loss"
                    stroke={palette[0]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                  <Line
                    type="monotone"
                    dataKey="test"
                    name="Test Loss"
                    stroke={palette[1]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            ) : (
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前结果未包含 Loss 曲线数据。
              </div>
            )}
          </TabsContent>

          {availability.oa ? (
            <TabsContent value="oa" className="mt-0 mb-0">
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={chartSeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} domain={[0, 100]} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatPercent} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  <Line
                    type="monotone"
                    dataKey="oa"
                    name="OA"
                    stroke={palette[2]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            </TabsContent>
          ) : (
            <TabsContent value="oa" className="mt-0 mb-0">
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前结果未包含 OA 数据。
              </div>
            </TabsContent>
          )}

          {availability.kappa ? (
            <TabsContent value="kappa" className="mt-0 mb-0">
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={chartSeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatFraction} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  <Line
                    type="monotone"
                    dataKey="kappa"
                    name="Kappa"
                    stroke={palette[3]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            </TabsContent>
          ) : (
            <TabsContent value="kappa" className="mt-0 mb-0">
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前结果未包含 Kappa 数据。
              </div>
            </TabsContent>
          )}

          {availability.precision ? (
            <TabsContent value="precision" className="mt-0 mb-0">
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={chartSeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatFraction} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  <Line
                    type="monotone"
                    dataKey="precision"
                    name="Precision"
                    stroke={palette[4]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            </TabsContent>
          ) : (
            <TabsContent value="precision" className="mt-0 mb-0">
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前结果未包含 Precision 数据。
              </div>
            </TabsContent>
          )}

          {availability.recall ? (
            <TabsContent value="recall" className="mt-0 mb-0">
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={chartSeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatFraction} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  <Line
                    type="monotone"
                    dataKey="recall"
                    name="Recall"
                    stroke={palette[0]}
                    strokeWidth={2}
                    dot={false}
                    connectNulls
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            </TabsContent>
          ) : (
            <TabsContent value="recall" className="mt-0 mb-0">
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前结果未包含 Recall 数据。
              </div>
            </TabsContent>
          )}

          {availability.classAccuracy ? (
            <TabsContent value="class-accuracy" className="mt-0 mb-0">
              <ResponsiveContainer width="100%" height={340}>
                <LineChart
                  data={classAccuracySeries}
                  margin={{ top: 16, right: 16, left: 12, bottom: 12 }}
                >
                  <CartesianGrid strokeDasharray="4 4" stroke="#e5e7eb" />
                  <XAxis dataKey="epoch" tickLine={false} axisLine={false} tickMargin={8} />
                  <YAxis tickLine={false} axisLine={false} tickMargin={4} domain={[0, 100]} />
                  <Tooltip cursor={{ strokeDasharray: '4 2' }} formatter={formatPercent} />
                  <Legend iconType="circle" verticalAlign="top" height={32} />
                  {classAccuracyKeys.map((key, index) => (
                    <Line
                      key={key}
                      type="monotone"
                      dataKey={key}
                      name={key}
                      stroke={palette[index % palette.length]}
                      strokeWidth={2}
                      dot={false}
                      connectNulls
                      isAnimationActive={false}
                    />
                  ))}
                </LineChart>
              </ResponsiveContainer>
            </TabsContent>
          ) : (
            <TabsContent value="class-accuracy" className="mt-0 mb-0">
              <div className="rounded-lg border border-dashed border-border/60 p-6 text-sm text-muted-foreground">
                当前任务未提供类别准确率数据。
              </div>
            </TabsContent>
          )}
        </Tabs>
      </CardContent>
    </Card>
  );
}
